#include "ir.h"
#include "delay.h"

void ir_init()
{
    IT0 = 1;  // 下降沿触发外部中断0
    EX0 = 1;  // 打开外部中断0 允许:1
    EA = 1;   // 打开总中断
    IRED = 1; // 初始化端口
}

void ir_receive_data()
{
    if (IRED == 0)
    {
        // 1.检测起始位 9ms脉冲+4.5ms空闲
        int start_cnt = 1000;
        while (!IRED && start_cnt)
        {
            // 等待引导信号9ms低电平结束，若超过10ms强制退出
            delay_10us(1);
            start_cnt--;
            if (start_cnt == 0)
            {
                // 低电平时间超过10ms,终止
                return;
            }
        }
        // 2.引导信号9ms低电平已过，进入4.5ms高电平
        if (IRED)
        {
            // 等待引导信号4.5ms高电平结束，若超时强制退出
            int start_cnt2 = 1000;
            while (IRED && start_cnt2)
            {
                delay_5us();
                start_cnt2--;
                if (start_cnt2 == 0)
                {
                    // 超时强制退出
                    return;
                }
            }

            // 3.接受bit数据,从低位开始接受
            for (i = 0; i < 4; i++)
            {
                unsigned char byte_data = ired_data[i];
                for (i = 0; i < 8; i++)
                {
                    unsigned char retFlag = 3;
                    retFlag = receive_bit(IRED);
                    if (retFlag == 3)
                    {
                        return;
                    }
                    byte_data >> 1;
                    if (retFlag)
                    {
                        byte_data |= 0x80;
                    }
                }
            }
        }
        // 4.验证反码
        if (ired_data[2] != ~ired_data[3])
        {
            return;
        }
    }
}

/**
 * red_out 即IRED
 */
unsigned char receive_bit(char red_out)
{
    // 3.接收数据 560us低，高560/1690
    int bit_cnt = 1200;
    while (!red_out && bit_cnt)
    {
        // 低电平持续600ms,超时退出
        delay_5us();
        bit_cnt--;
        if (bit_cnt == 0)
        {
            return 3;
        }
    }

    // 接受高电平数据,可能是0或者1
    int bit_cnt2 = 0;
    while (red_out)
    {
        delay_5us();
        bit_cnt2++;
        if (bit_cnt2 >= 360)
        {
            // 超过1800us还是高电平,无效数据
            return 3;
        }
    }
    if (bit_cnt2 > 120)
    {
        // 高电平时间超过560us，说明是bit 1
        return 1;
    }
    return 0;
}
